#include "app_common.h"
#include <imp/imp_log.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include "RealTimeTalkBack.h"
#include "NetAudio.h"
#include "Audio.h"
#include "OnlineToolCallBack.h"
#include "Sqlist_List.h"
#include "IBT_List.h"
#include "g711.h"


enum{
	CHANNEL_AUDIO_DATA_OFF=0,
    CHANNEL_AUDIO_DATA_ON=1,
};


CNetAudioList g_NetAudioList;




void Net_AudioList_init()
{
	g_NetAudioList.m_Play_Switch=FALSE;
	g_NetAudioList.m_Play_Number=0;								//播放人数初始化
	IBT_List_QueueInit(&(g_NetAudioList.m_Play_Queue));			//初始化插入人员
	pthread_mutex_init(g_NetAudioList.m_Send_hmutex,NULL);		//初始化锁			
	g_NetAudioList.m_Send_Swicht=FALSE;							//关闭发送线程
	g_NetAudioList.m_Send_Number=0;								//发送人数初始化
	IBT_List_QueueInit(&(g_NetAudioList.m_SendPakcet_Queue));//初始化发送数据包队列
	List_Init(&(g_NetAudioList.m_Send_List.Head));				//初始化音频发送人员表头
}







/*
 *	函数说明：语音对讲，播放上位机来的数据
 */
void *Net_AudioPlay_Thread(void *argc)
{
	pthread_detach(pthread_self());
	SET_THREAD_NAME("Net_AudioPlay_Thread");
	IBTList *Pos;
	CAudioPlayPacket *Position;
	int ret;
	while(g_NetAudioList.m_Play_Switch==TRUE)
	{
		
			IBT_List_PopQueueFromHead(&(g_NetAudioList.m_Play_Queue),&(g_NetAudioList.m_Play_Queue.queue),&Pos);
			if(Pos!=NULL)
			{
			Position=List_Enter(Pos,CAudioPlayPacket,queue);
			ret=AudioTalkPlayFrame(Position->m_buffer,Position->m_length);
            if(ret<0)LOGE("Ret Error \n");
            free(Position->m_buffer);
            free(Position);
            }
            else 
            {
			usleep(10*1000);
            }
            
	}	
	while(1)//出去前弹出所有的音频
	{
		IBT_List_PopQueueFromHead(&(g_NetAudioList.m_Play_Queue),&(g_NetAudioList.m_Play_Queue.queue),&Pos);
		if(Pos==NULL)break;
		Position=List_Enter(Pos,CAudioPlayPacket,queue);
		free(Position->m_buffer);
        free(Position);
	}
	pthread_exit(0);
	return 0;
}


void RealseAudioPacket(CAudioSendPakcet **Packet)
{
	if((*Packet)!=NULL)
	{
		int count;
		pthread_mutex_lock(&((*Packet)->m_hmutex));
		(*Packet)->m_count--;
		count=(*Packet)->m_count;	
		pthread_mutex_unlock(&((*Packet)->m_hmutex));
		if(count==0)
		{	
				pthread_mutex_destroy(&((*Packet)->m_hmutex));
				free((*Packet)->m_buffer);
				free((*Packet));
				(*Packet)=NULL;

		}	
		
	}
	
}

void ReleaseSendAudioPacket(const struct tagMsgHdr *msg)
{
	CAudioSendPakcet **Packet=(CAudioSendPakcet **)(msg->context);
	if((*Packet)!=NULL)
	{
		int count;
		pthread_mutex_lock(&((*Packet)->m_hmutex));
		(*Packet)->m_count--;
		count=(*Packet)->m_count;	
		pthread_mutex_unlock(&((*Packet)->m_hmutex));
		if(count==0)
		{
			pthread_mutex_destroy(&((*Packet)->m_hmutex));
			free((*Packet)->m_buffer);
			free((*Packet));
			(*Packet)=NULL;
		}	
		
	}
}



void NET_AudioSend(struct conn *m_conn,CAudioSendPakcet **Packet)
{
	if(m_conn==NULL)return;
	if((*Packet)==NULL)return;
	
	DVRIP head;
    memset(&head, 0, sizeof(head));
    head.dvrip_cmd= ACK_REQ_AUDIO_DATA;
    head.dvrip_p[0]     = 0;
    head.dvrip_extlen	= (*Packet)->m_length;
    msghdr_t msghdr[2];

    memset(&msghdr, 0, sizeof(msghdr));
    pthread_mutex_lock(&((*Packet)->m_hmutex));
    (*Packet)->m_count++;
    pthread_mutex_unlock(&((*Packet)->m_hmutex));
    
    msghdr[0].msgCmd   = ACK_REQ_AUDIO_DATA;
    msghdr[0].chn      = 0;
    msghdr[0].buf      = &head;
    msghdr[0].buf_len  = sizeof(head);
    msghdr[0].msg_flags= MSG_FLAGS_MORE ;
    msghdr[0].next     = &msghdr[1];

    
    msghdr[1].msgCmd   = ACK_REQ_AUDIO_DATA;
    msghdr[1].chn      = 0;
    msghdr[1].buf      = (*Packet)->m_buffer;
    msghdr[1].buf_len  = (*Packet)->m_length;
    msghdr[1].msg_flags= 0;
    msghdr[1].callback = ReleaseSendAudioPacket;
    msghdr[1].context  = Packet;
    DvrNetSendChain(m_conn, msghdr);
}



/*
 *函数说明：语音对讲，上传数据
 */

void *Net_AudioSend_Thread(void *argc)
{
	pthread_detach(pthread_self());
	SET_THREAD_NAME("Net_AudioSend_Thread");
	IBTList 			*Pack_Pos;
	List_Head 			*Send_Pos;
	CAudioSendList		*P_Send;
	CAudioSendPakcet 	*P_Packet;
	
	while(g_NetAudioList.m_Send_Swicht)
	{	
		IBT_List_PopQueueFromHead(&(g_NetAudioList.m_SendPakcet_Queue),&(g_NetAudioList.m_SendPakcet_Queue.queue),&Pack_Pos);
		if(Pack_Pos!=NULL)//有包
		{
			//P_Packet=container_of(Pack_Pos,CAudioSendPakcet,queue);
			P_Packet=List_Enter(Pack_Pos,CAudioSendPakcet,queue);
			pthread_mutex_lock(g_NetAudioList.m_Send_hmutex);
			List_For_Each(Send_Pos, &(g_NetAudioList.m_Send_List.Head))
			{  //发送
				if(Send_Pos==NULL)continue;
				P_Send=List_Enter(Send_Pos, CAudioSendList,Head);
				if(P_Send==NULL)continue ;
				NET_AudioSend(P_Send->m_conn,&P_Packet);
			}
			pthread_mutex_unlock(g_NetAudioList.m_Send_hmutex);
			RealseAudioPacket(&P_Packet);
		}
		else 
		{
			usleep(10*1000);//10
		}
	}
	while(1)
	{
		IBT_List_PopQueueFromHead(&(g_NetAudioList.m_SendPakcet_Queue),&(g_NetAudioList.m_SendPakcet_Queue.queue),&Pack_Pos);
		if(Pack_Pos==NULL)break;
		P_Packet=List_Enter(Pack_Pos,CAudioSendPakcet,queue);
		RealseAudioPacket(&P_Packet);
	}
	pthread_exit(0);
	return 0;

}

void Net_AudioSend_AddNumber(struct conn *m_conn)
{
	CAudioSendList *New_SendNumber=(CAudioSendList *)malloc(sizeof(CAudioSendList));
	if(New_SendNumber==NULL)return;
	New_SendNumber->m_conn=m_conn;
	pthread_mutex_lock(g_NetAudioList.m_Send_hmutex);
	List_Add_Tail(&(New_SendNumber->Head), &(g_NetAudioList.m_Send_List.Head));//向链表中加入成员
	pthread_mutex_unlock(g_NetAudioList.m_Send_hmutex);
	
}

void Net_AudioSend_DeleteNumber(struct conn* m_conn)
{
	CAudioSendList *P_SendNumber;
	List_Head *Pos,*Next;
	pthread_mutex_lock(g_NetAudioList.m_Send_hmutex);
	List_For_Each_Safe(Pos, Next, &(g_NetAudioList.m_Send_List.Head))
	{
		P_SendNumber=List_Enter(Pos, CAudioSendList, Head);
		if(P_SendNumber&&P_SendNumber->m_conn==m_conn)
		{
		List_Del(Pos);
		free(P_SendNumber);
		}
		
	}
	pthread_mutex_unlock(g_NetAudioList.m_Send_hmutex);
}






/*
 *	函数说明：语音对讲添加数据包
 */
void Net_AudioPlayer_AddPacket(unsigned char *buffer,unsigned int length)
{
	//插入新成员
	CAudioPlayPacket *New_Audio_List;
	New_Audio_List=(CAudioPlayPacket *)malloc(sizeof(CAudioPlayPacket));
	if(New_Audio_List==NULL)
	{
	free(buffer);
	return ;
	}
	New_Audio_List->m_buffer	=buffer;
	New_Audio_List->m_length	=length;
	IBT_List_PushQueueToTail(&(g_NetAudioList.m_Play_Queue),&(g_NetAudioList.m_Play_Queue.queue),&(New_Audio_List->queue));
}



void Net_AudioSendStart(struct conn *m_conn)
{
	g_NetAudioList.m_Play_Number++;
	Net_AudioSend_AddNumber(m_conn);//注册音频成员
	if(g_NetAudioList.m_Send_Swicht==FALSE&&g_NetAudioList.m_Send_Number==0)
	{
	g_NetAudioList.m_Send_Swicht=TRUE;
	pthread_create(&(g_NetAudioList.m_Send_ThreadID),NULL,Net_AudioSend_Thread,NULL);
	}
	
	g_NetAudioList.m_Send_Number++;
}

void Net_AudioSendStop(struct conn *m_conn)
{
	g_NetAudioList.m_Send_Number--;
	if(g_NetAudioList.m_Send_Number==0&&g_NetAudioList.m_Send_Swicht==TRUE)
	{		
		g_NetAudioList.m_Send_Swicht=FALSE;
	}

}


/*
 *函数说明：对讲开始
 */
void Net_AudioPlayStart()
{	
	
	if(g_NetAudioList.m_Play_Switch==FALSE)
	{
	OnlineAudioStart_CallBack(0,0,0,0);
	//AudioTalkPlaySet(0,0,0,0);	//测试用
	pthread_create(&(g_NetAudioList.m_Play_ThreadID),NULL,Net_AudioPlay_Thread,NULL);
	g_NetAudioList.m_Play_Switch=TRUE;
	
	}
	
}


/*
 *函数说明：播放停止
 */
void Net_AudioPlayStop() 
{	
	g_NetAudioList.m_Play_Number--;
	if(g_NetAudioList.m_Play_Number==0)
	{
	OnlineAudioStop_CallBack();
	g_NetAudioList.m_Play_Switch=FALSE;
	//AudioTalkPlayFinish();	//测试用
	}

}

static int g711u_decode(void* pInData,int length,void* pOutData)
{
    unsigned char buf[2048] = {0};
    int decode_bytes = 0;	

	if(length <= 2048)
	    memcpy(buf,(unsigned char*)pInData,length);
	else
		memcpy(buf,(unsigned char*)pInData,2048);
	
	g711_udec(buf, length, (unsigned char *)pOutData, &decode_bytes);

	return decode_bytes;
}

/*
 * 产测对讲音频发送和接收开启和关闭消息处理 MsgProcess调用
 */
int Audio_FilterCallback(struct conn *c, DVRIP *pHead)
{

	//上位机先发来1d然后发来c0,两次一共两个包
	//发送回去应答的包为1d的包，在原来vfware中的OnAudioCapture，发送的数据是设备编码完后的音频
	//
	switch(pHead->dvrip_cmd)
	{

		case REQ_SEND_AUDIO:  //1d  接收产测音频
		{		
			
	        
			if((2==pHead->dvrip_p[0]))
			{
				if ( pHead->dvrip_extlen <= 0 || pHead->dvrip_extlen > 10*1024)
                {	
	                DVRIP head;
			        msghdr_t msghdr;
			        memset(&head, 0, sizeof(head));
			        memset(&msghdr, 0, sizeof(msghdr));
			        
			        msghdr.msgCmd   = ACK_SEND_AUDIO;
			        msghdr.chn      = pHead->dvrip_p[4];
			        msghdr.buf      = &head;
			        msghdr.buf_len  = sizeof(DVRIP);
			        msghdr.msg_flags= MSG_FLAGS_MORE ;            

			        head.dvrip_cmd= ACK_SEND_AUDIO;    
			        head.dvrip_p[4] = pHead->dvrip_p[4];
                	head.dvrip_p[0] = 0;
                    DvrNetSendMsg(c,&msghdr);
                    return 0;
                }
                Net_AudioPlayStart();
                short *pPcmData;				
				int Pcm_Len=0;
            	pPcmData=(short *)malloc(4096);
            	if(pPcmData==NULL)
            	{
				return 0;
            	}
            	memset(pPcmData,0,4096);
                unsigned char *Audio_Buffer=(unsigned char *)malloc(pHead->dvrip_extlen);
                if(Audio_Buffer==NULL)
                {
                free(pPcmData);
                return 0;
                }
                
                memset(Audio_Buffer,0,pHead->dvrip_extlen);
                memcpy(Audio_Buffer,(&(pHead->dvrip_p[24])),pHead->dvrip_extlen);
                unsigned int Audio_Length=pHead->dvrip_extlen;
				
				/*if(Audio_Length > Audio_BufferMax)
				{
					int i;
					for(i = 0; i < Audio_Length/Audio_BufferMax; i++)
					{
						OnlineAudioSendData_CallBack(Audio_Buffer + i*Audio_BufferMax,Audio_BufferMax);
					}
					
					if(Audio_Length%Audio_BufferMax != 0)
						OnlineAudioSendData_CallBack(Audio_Buffer+ i*Audio_BufferMax,Audio_Length - i*Audio_BufferMax);
				}
				else
				{
					OnlineAudioSendData_CallBack(Audio_Buffer,Audio_Length);
				}*/
				OnlineAudioSendData_CallBack(Audio_Buffer,Audio_Length);
				
	            //free(Audio_Buffer);//测试用
	            
                Pcm_Len=g711u_decode((void*)(&(pHead->dvrip_p[24])),pHead->dvrip_extlen,(void*)pPcmData);//解码输出到PcmData上
                Net_AudioPlayer_AddPacket((unsigned char *)pPcmData,Pcm_Len);
                
				//head.dvrip_p[0] = 0;
           	 	//DvrNetSendMsg(c,&msghdr);
            	return 0;
			}
			else if (3 == pHead->dvrip_p[0])
            {   
            
            	Net_AudioPlayStop(); 
                
            	DVRIP head;
		        msghdr_t msghdr;
		        memset(&head, 0, sizeof(head));
		        memset(&msghdr, 0, sizeof(msghdr));
		        
		        msghdr.msgCmd   = ACK_SEND_AUDIO;
		        msghdr.chn      = pHead->dvrip_p[4];
		        msghdr.buf      = &head;
		        msghdr.buf_len  = sizeof(DVRIP);
		        msghdr.msg_flags= MSG_FLAGS_MORE ;            

		        head.dvrip_cmd= ACK_SEND_AUDIO;    
		        head.dvrip_p[4] = pHead->dvrip_p[4];        	
                head.dvrip_p[0] = 1;
                DvrNetSendMsg(c,&msghdr);
                
               
                return 0;                    
			}
			break;
		}
		case REQ_AUDIO_DATA: 
				if (CHANNEL_AUDIO_DATA_ON == pHead->dvrip_p[4])
				{
				Net_AudioSendStart(c);
				
				}
				else if(CHANNEL_AUDIO_DATA_OFF == pHead->dvrip_p[4])
				{  
				Net_AudioSendStop(c);
				}
		break;

        default:
        break;
	

		}



	return 0;
}




/*
 * 音频喂流接口，返回数据给上位机
 * 参数说明：
 * m_buffer: 音频流
 * Length：  长度
 */
void OnlineAudio_Updata(unsigned char *m_buffer,unsigned int Length)
{
	if(g_NetAudioList.m_Send_Number>0&&g_NetAudioList.m_Send_Swicht==TRUE)//只有开启了才会取流
	{
		CAudioSendPakcet *P_pack=(CAudioSendPakcet *)malloc(sizeof(CAudioSendPakcet));
		if(P_pack==NULL)
		{
		LOGE("Audio P_pack malloc errror \n");
		}
		P_pack->m_buffer=(unsigned char *)malloc(Length+40);
		
		if(P_pack->m_buffer==NULL)
		{
		free(P_pack);
		LOGE("Audio_malloc buffer errror \n");
		}
		memset(P_pack->m_buffer,0,Length+40);
		int head_len;
		head_len=FormStandHead(P_pack->m_buffer,Length,3,0);  //3 音频头
		memcpy((P_pack->m_buffer)+head_len+4,m_buffer,Length);
		pthread_mutex_init(&(P_pack->m_hmutex),NULL);
		P_pack->m_length=Length+4+head_len;
		P_pack->m_count=1;
		IBT_List_PushQueueToTail(&(g_NetAudioList.m_SendPakcet_Queue),&(g_NetAudioList.m_SendPakcet_Queue.queue),&(P_pack->queue));
	}
}











